import React from 'react';
import { Surface, Shape, Path, Text, Group } from '@react-native-community/art';
import Orientation from 'react-native-orientation';
import { getMacAddress } from 'react-native-device-info';
export let DEVICE_WIDTH = Dimensions.get('window').width;
export let DEVICE_HEIGHT = Dimensions.get('window').height;
import Other from './public/components/Other';
import webSocket from './public/js/webSocket';
import {
  StyleSheet,
  View,
  PanResponder,
  Dimensions,
} from 'react-native';
import UserMessages from './public/js/UserMessages';
class User extends React.Component {
  constructor(props) {
    super(props);
    // const users = [...(props.users)];
    // const circlePaths = [...(props.circlePaths)];
    // for (let i = 3; i < 10; i++) {
    //   const temp = {
    //     id: i,
    //     name: `ht${i}`,
    //     x: Math.random() * 3 * DEVICE_WIDTH - DEVICE_WIDTH,
    //     y: Math.random() * 3 * DEVICE_HEIGHT - DEVICE_HEIGHT,
    //     messages: new UserMessages(),
    //   };
    //   const x = temp.x - (this.props.users[0].x - DEVICE_WIDTH / 2);
    //   const y = temp.y - (this.props.users[0].y - DEVICE_HEIGHT / 2);
    //   const temp2 = {
    //     x: x,
    //     y: y,
    //     circlePath: new Path()
    //       .moveTo(x, y)
    //       .arc(10, 0, 5, 5, 0)
    //       .arc(-10, 0, 5, 5, 0),
    //   };
    //   users.push(temp);
    //   circlePaths.push(temp2);
    // }
    // this.props.setUsers(users);
    // this.props.setCirclePaths(circlePaths);
  }
  draw(touchX, touchY) {
    let updateX = (touchX - DEVICE_WIDTH / 2) / 40;
    let updateY = (touchY - DEVICE_HEIGHT / 2) / 40;
    let a = this.props.users;
    let b = this.props.circlePaths;
    for (let i in this.props.circlePaths) {
      if (i == 0) {
        a[i].x = a[i].x + updateX;
        a[i].y = a[i].y + updateY;
        continue;
      }
      b[i].x = b[i].x - updateX * 0.5;
      b[i].y = b[i].y - updateY * 0.5;
      b[i].circlePath = new Path()
        .moveTo(b[i].x, b[i].y)
        .arc(10, 0, 5, 5, 0)
        .arc(-10, 0, 5, 5, 0);
    }
    this.props.setUsers(a);
    this.props.setCirclePaths(b);
  }
  draw2(dx, dy) {
    let a = this.props.users;
    let b = this.props.circlePaths;
    for (let i in this.props.circlePaths) {
      if (i == 0) {
        a[i].x = a[i].x + (dx * 0.5) / 10;
        a[i].y = a[i].y + (dy * 0.5) / 10;
        continue;
      }
      b[i].x = b[i].x - (dx * 0.5) / 10;
      b[i].y = b[i].y - (dy * 0.5) / 10;
      b[i].circlePath = new Path()
        .moveTo(b[i].x, b[i].y)
        .arc(10, 0, 5, 5, 0)
        .arc(-10, 0, 5, 5, 0);
    }
    this.props.setUsers(a);
    this.props.setCirclePaths(b);
    this.props.ws.send(JSON.stringify({ u: 1, x: a[0].x, y: a[0].y }));
    // console.log(this.props.users);
  }
  draw3(dx, dy) {
    let a = this.props.users;
    let long = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
    let c = a[0].tail;
    let r = 5;
    let x1 = this.props.circlePaths[0].x + 5;
    let y1 = this.props.circlePaths[0].y;
    let x2 = this.props.circlePaths[0].x + 5 - (5 * (r * dx)) / long;
    let y2 = this.props.circlePaths[0].y - (5 * (r * dy)) / long;
    let tail_long = 20;
    c.x2 = x1 + (20 / tail_long) * (x2 - x1);
    c.y2 = y1 + (20 / tail_long) * (y2 - y1);
    (c.circlePath = new Path()
      .moveTo(this.props.circlePaths[0].x + 5, this.props.circlePaths[0].y)
      .lineTo(c.x2, c.y2)),
      (a[0].tail = c);
    // this.setState({ users: a });
    // this.forceUpdate();
  }
  render() {
    return (
      <View>
        <Surface
          style={styles.User}
          width={DEVICE_WIDTH}
          height={DEVICE_HEIGHT}>
          <Shape
            fill={'rgba(226,219,226,' + 0.8 + ')'}
            stroke={'#603030'}
            strokeWidth={6}
            d={this.props.users[0].tail.circlePath}
          />
          {this.props.users.map((item, index) => (
            <Group key={index}>
              <Shape
                fill={'rgba(226,219,226,' + 0.8 + ')'}
                stroke={'#603030'}
                strokeWidth={10}
                d={this.props.circlePaths[index].circlePath}
              />
              <Text
                strokeWidth={2}
                stroke="rgb(150,60,74)"
                font='16px "Helvetica Neue", "Helvetica", Arial'
                x={
                  this.props.circlePaths[index].x +
                  2 -
                  5 * this.props.users[index].name.length
                }
                y={this.props.circlePaths[index].y - 35}>
                {this.props.users[index].name}
              </Text>
              {this.props.users[index].messages.messages.map((m_item, m_index) => (
                <Text
                  key={m_index}
                  strokeWidth={2}
                  stroke="#000"
                  font="20px YouYuan SC"
                  x={this.props.circlePaths[index].x + 20}
                  y={this.props.circlePaths[index].y - 20 + 20 * m_index}>
                  {this.props.users[index].messages.messages[m_index]}
                </Text>
              ))}
            </Group>
          ))}
        </Surface>
      </View>
    );
  }
}
class WaterParticle extends React.Component {
  constructor() {
    super();
    console.log('start');
    this.state = { waterParticles: [], circlePaths: [] };
    for (let i = 0; i < 30; i++) {
      const temp = {
        x: (~~(Math.random() * 10) * DEVICE_WIDTH) / 10,
        y: (~~(Math.random() * 10) * DEVICE_HEIGHT) / 10,
        speed: 0.3 + Math.random(),
      };
      const circlePath = new Path()
        .moveTo(temp.x, temp.y)
        .arc(1, 0, 0.5, 0.5, 0)
        .arc(-1, 0, 0.5, 0.5, 0);
      this.state.waterParticles.push(temp);
      this.state.circlePaths.push(circlePath);
    }
  }
  draw(touchX, touchY) {
    let updateX = (touchX - DEVICE_WIDTH / 2) / 40;
    let updateY = (touchY - DEVICE_HEIGHT / 2) / 40;
    let a = this.state.waterParticles;
    let b = this.state.circlePaths;
    for (let i in this.state.waterParticles) {
      a[i].x = (a[i].x - updateX * a[i].speed + DEVICE_WIDTH) % DEVICE_WIDTH;
      a[i].y = (a[i].y - updateY * a[i].speed + DEVICE_HEIGHT) % DEVICE_HEIGHT;
      b[i] = new Path()
        .moveTo(a[i].x, a[i].y)
        .arc(1, 0, 0.5, 0.5)
        .arc(-1, 0, 0.5, 0.5);
    }
    this.setState({ waterParticles: a, circlePaths: b });
  }
  draw2(dx, dy) {
    let a = this.state.waterParticles;
    let b = this.state.circlePaths;
    for (let i in this.state.waterParticles) {
      a[i].x = (a[i].x - (dx * a[i].speed) / 10 + DEVICE_WIDTH) % DEVICE_WIDTH;
      a[i].y =
        (a[i].y - (dy * a[i].speed) / 10 + DEVICE_HEIGHT) % DEVICE_HEIGHT;
      b[i] = new Path()
        .moveTo(a[i].x, a[i].y)
        .arc(1, 0, 0.5, 0.5)
        .arc(-1, 0, 0.5, 0.5);
    }
    this.setState({ waterParticles: a, circlePaths: b });
  }
  render() {
    return (
      <View>
        <View>
          <Surface
            style={styles.WaterParticle}
            width={DEVICE_WIDTH}
            height={DEVICE_HEIGHT}>
            {this.state.waterParticles.map((item, index) => (
              <Shape
                key={index}
                fill={
                  'rgba(226,219,226,' +
                  this.state.waterParticles[index].opacity +
                  ')'
                }
                stroke={'#3366FF'}
                strokeWidth={4}
                d={this.state.circlePaths[index]}
              />
            ))}
          </Surface>
        </View>
      </View>
    );
  }
}
export default class App4 extends React.Component {
  constructor(props) {
    super(props);
    Orientation.lockToLandscape(); //强制横屏
    getMacAddress().then(mac => { this.mac = mac; });
    this.url = '';
    this.panResponder = PanResponder.create({
      onStartShouldSetPanResponder: (evt, gestureState) => true,
      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      onPanResponderGrant: (evt, gestureState) => {
        // this.highlight();
      },
      // 移动手势监听回调
      onPanResponderMove: (evt, gestureState) => {
        // Alert.alert("111")
        const X = gestureState.dx;
        const Y = gestureState.dy;
        this.draw2(X, Y);
        // }
      },
      // // 手势动作结束回调
      onPanResponderEnd: (evt, gestureState) => {
      },
      // 手势释放, 响应者释放回调
      onPanResponderRelease: (evt, gestureState) => {
        // this.unhighlight();
      },
    });
    this.ws = new WebSocket('ws://192.168.50.21:9999');
    this.ws.onopen = () => {
      console.log('connect');
    };
    this.ws.onmessage = ({ data }) => {
      data = JSON.parse(data);
      if (data.u !== 1) {
        const u = this.state.users;
        const p = this.state.circlePaths;
        u[1].x = data.x;
        p[1].x = data.x;
        u[1].y = data.y;
        p[1].y = data.y;
        p[1].circlePath = new Path()
          .moveTo(p[1].x, p[1].y)
          .arc(10, 0, 5, 5, 0)
          .arc(-10, 0, 5, 5, 0);
        this.setState({ users: u, circlePaths: p });
      }
    };
    this.state = {
      users: [
        {
          id: '2',
          name: 'gfxm',
          x: Math.random() * 3 * DEVICE_WIDTH - DEVICE_WIDTH,
          y: Math.random() * 3 * DEVICE_HEIGHT - DEVICE_HEIGHT,
          messages: new UserMessages(),
          tail: {
            x2: DEVICE_WIDTH / 2 + 5,
            y2: DEVICE_HEIGHT / 2 + 30,
            circlePath: new Path()
              .moveTo(DEVICE_WIDTH / 2 + 5, DEVICE_HEIGHT / 2)
              .lineTo(DEVICE_WIDTH / 2 + 5, DEVICE_HEIGHT / 2 + 30),
          },
        }, {
          id: '3',
          name: 'hxy',
          x: Math.random() * 3 * DEVICE_WIDTH - DEVICE_WIDTH,
          y: Math.random() * 3 * DEVICE_HEIGHT - DEVICE_HEIGHT,
          messages: new UserMessages(),
        },
      ],
      circlePaths: [
        {
          x: DEVICE_WIDTH / 2,
          y: DEVICE_HEIGHT / 2,
          circlePath: new Path()
            .moveTo(DEVICE_WIDTH / 2, DEVICE_HEIGHT / 2)
            .arc(10, 0, 5, 5, 0)
            .arc(-10, 0, 5, 5, 0),
        }, {
          x: DEVICE_WIDTH / 2,
          y: DEVICE_HEIGHT / 2,
          circlePath: new Path()
            .moveTo(DEVICE_WIDTH / 2, DEVICE_HEIGHT / 2)
            .arc(10, 0, 5, 5, 0)
            .arc(-10, 0, 5, 5, 0),
        },
      ],
      backgroundColor: 'white',
      x: 0,
      y: 0,
      userTadpole: {
        id: 1,
      },
      tadpoles: {},
      camera: {
        x: 0,
        y: 0,
      },
    };
    this.draw = this.draw.bind(this);
    this.draw2 = this.draw2.bind(this);
    this.setUsers = this.setUsers.bind(this);
    this.setCirclePaths = this.setCirclePaths.bind(this);
    this.onMessages = this.onMessages.bind(this);
    this.getUsersObject = this.getUsersObject.bind(this);
  }
  setCirclePaths(circlePaths) {
    this.setState({
      circlePaths,
    });
  }
  setUsers(users) {
    this.setState({
      users,
    });
    // this.ws.send();
  }
  highlight() {
    this.setState({
      backgroundColor: 'silver',
    });
  }
  unhighlight() {
    this.setState({
      backgroundColor: 'white',
    });
  }
  draw(X, Y) {
    this.WaterParticle.draw(X, Y);
    this.User.draw(X, Y);
  }
  draw2(DX, DY) {
    this.WaterParticle.draw2(DX, DY);
    this.User.draw2(DX, DY);
    this.User.draw3(DX, DY);
  }
  async getInitData() {
    const response = await fetch(`http://${this.url}:8080/user/addUser?umac=${this.mac}`);
    const data = await response.text();
    const { utoken, ytoken } = data;
    this.setState({
      utoken,
      ytoken,
      ws: webSocket(this.onMessages, utoken, `ws://${this.url}:8080/imserver/${this.mac}`),
    });
  }
  getUsersObject() {
    const userMessages = {};
    for (const item of this.state.users) {
      userMessages[item.id] = item.messages;
    }
  }
  onMessages({ data }) {
    const userMessages = this.getUsersObject();
    const users = [];
    const circlePaths = [];
    console.log(data);
    // const t = RegExp(/(?<=}),/, 'g');
    data.replaceAll('},{', '}qqx,{');
    data = data.slice(1)
      .slice(0, -1)
      .split('qqx,')
      .map((item) => {
        console.log(item);
        return JSON.parse(item);
      });
    console.log(data);
    for (const item of data) {
      const temp = {
        id: item.umac,
        name: item.name ?? 'noname',
        x: item.x,
        y: item.y,
        messages: userMessages[item.umac] ?? new UserMessages(),
      };
      const x = temp.x - (this.state.users[0].x - DEVICE_WIDTH / 2);
      const y = temp.y - (this.state.users[0].y - DEVICE_HEIGHT / 2);
      const temp2 = {
        x: x,
        y: y,
        circlePath: new Path()
          .moveTo(x, y)
          .arc(10, 0, 5, 5, 0)
          .arc(-10, 0, 5, 5, 0),
      };
      if (data.id === this.umac) {
        users.unshift(temp);
        circlePaths.unshift(temp2);
      } else {
        users.push(temp);
        circlePaths.push(temp2);
      }
    }
  }
  render() {
    return (
      <View>
        <View style={[styles.body, { backgroundColor: this.state.backgroundColor }]}
          {...this.panResponder.panHandlers}>
          <WaterParticle ref={node => (this.WaterParticle = node)} />
          <User ws={this.ws} users={this.state.users} circlePaths={this.state.circlePaths} setUsers={this.setUsers} setCirclePaths={this.setCirclePaths} ref={node => (this.User = node)} />
        </View>
        <Other users={this.state.users} setUsers={this.setUsers} ws={this.ws} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  body: {
    position: 'absolute',
    zIndex: -1,
    width: DEVICE_WIDTH,
    height: DEVICE_HEIGHT,
  },
  WaterParticle: {
    position: 'absolute',
    width: DEVICE_WIDTH,
    height: DEVICE_HEIGHT,
  },
  User: {
    position: 'absolute',
    width: DEVICE_WIDTH,
    height: DEVICE_HEIGHT,
    elevation: 10,
  },
});
